#!/bin/bash

# 定义一个关联数组(字典)来存储单词及其出现次数
declare -A word_freq

# 虚词表
ignore_words=(
    #冠词：如
    "a" "an" "the"
    #介词：如
    "in" "on" "at" "for" "of" "to" "from" "above" "behind" "by" "with" "about"
    #助动词：如
    "is" "are" "have" "do" "be" "not" "will" "would" "was" "has" "have" "had" "haven" "could" "can"
    # 连词：如
    "and" "but" "or" "before" "that" "which" "so" "only"
    "then" "because" "if" "also" "when" "where" "how" "what" "as"
    # 感叹词：如
    "oh" "wow" "well" "hi"
    #代词
    "he" "she" "it" "they" "we" "his" "her" "its" "their" "our" "this" "these" "that" "those"
    #限定词
    "any" "some" "all" "none" "no" "one" "each" "every" "which" "many" "much" "another"
)

# 获取单词的单数形式
get_singular_form() {
    local word=$1
    local singular=$word

    # 直接加s型
    if [[ $word =~ s$ ]] && ! [[ $word =~ (bus|domino|echo|embargo|hero|potato|torpedo|veto)$ ]]; then
        singular="${word%s}"
    # 以es结尾的单词
    elif [[ $word =~ (ches|shes|xes|zes)$ ]]; then
        singular="${word%es}"
    # 以ies结尾的单词
    elif [[ $word =~ ies$ ]]; then
        singular="${word%ies}y"
    # 以ves结尾的单词
    elif [[ $word =~ ves$ ]]; then
        singular="${word%ves}f"
    fi

    echo "$singular"
}

build_dict() {
    # 遍历单词数组，统计每个单词的出现次数
    for word in "${words_array[@]}"; do
        singular_word=$(get_singular_form "$word")

        if [[ ${#singular_word} -gt 1 ]]; then # 忽略空字符串
            # 检查是否是虚词
            is_ignore_word=false
            for ignore_word in "${ignore_words[@]}"; do
                if [[ $singular_word == $ignore_word || $word == $ignore_word ]]; then
                    is_ignore_word=true
                    break
                fi
            done
            if [[ $is_ignore_word == false ]]; then
                # 检查单词是否为复数形式，并转换为单数形式
                if [[ -v word_freq[$singular_word] ]]; then
                    word_freq[$singular_word]=$((word_freq[$singular_word] + 1))
                else
                    word_freq[$singular_word]=1
                fi
            fi
        fi
    done
}

# 插入排序函数, 对字典word_freq，按值从大到小的顺序排序
insert_sort() {
    # 字典
    local -n dict=$1
    # 已经有序的单词表
    local -a sorted=()
    # 已经有序的频次表
    local -a sorted_freq=()

    # 遍历字典的所有键
    for word in "${!dict[@]}"; do
        local count=${dict[$word]}
        local inserted=false

        # 遍历 sorted 表，找到第一个比当前单词出现次数小的项
        for ((i = 0; i < ${#sorted[@]}; i++)); do
            #若找到，则将当前单词插入到 sorted 表对应位置，将频次插入到 sorted_freq 表对应位置
            if ((count > ${sorted_freq[i]})); then
                sorted=("${sorted[@]:0:$i}" "$word" "${sorted[@]:$i}")
                sorted_freq=("${sorted_freq[@]:0:$i}" "$count" "${sorted_freq[@]:$i}")
                inserted=true
                break
            fi
        done

        # 若找不到，则将单词插入到 sorted 表末尾, 更新 sorted_freq 次数
        if ! $inserted; then
            sorted+=("$word")
            sorted_freq+=("$count")
        fi
    done

    # 返回单词表
    echo "${sorted[@]}"
}

print_result() {
    # 提示用户输入打印数量
    read -p "Enter the number of words to print (default is 50): " input
    if [[ -n $input ]]; then
        print_count=$input
    else
        print_count=50
    fi
    count=0
    printf "%-30s %-10s %-10s\n" "Word" "Count" "Bar Chart"
    printf "%-30s %-10s %-10s\n" "----" "-----" "---------"
    for word in $sorted_words; do
        if ((count >= print_count)); then
            break
        fi
        printf "%-30s %-10d " "$word" "${word_freq[$word]}"
        for ((i = 0; i < word_freq[$word]; i++)); do
            printf "*"
        done
        printf "\n"
        ((count++))
    done
}

main() {

    # 检查参数
    if [[ $# -ne 1 ]]; then
        echo "Usage: $0 [filepath]"
        exit 1
    fi

    # 检查文件是否存在
    if [[ ! -f "$1" ]]; then
        echo "File not found: $1"
        exit 1
    fi

    # 读取文件内容，转换为小写，并将所有非字母字符替换为空格
    processed_text=$(cat "$1" | tr '[:upper:]' '[:lower:]' | tr -c '[:alpha:]' ' ')

    # 将处理后的文本按空格分割成单词数组
    read -r -a words_array <<<"$processed_text"

    # 建立统计字典
    build_dict

    # 调用排序函数并打印结果
    sorted_words=$(insert_sort word_freq)

    print_result
}

main "$@"
